From 84b4dfe81363c7bf8afce83ef3aea6b041df7a55 Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Fri, 3 Oct 2025 16:34:15 +0200 Subject: [PATCH] config: clamp ra_mininterval, ra_maxinterval, ra_lifetime at load time MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit clamp values to RFC defined limits. First set ra_maxinterval, then ra_mininterval adjusts based on max. Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcpd/pull/225 Signed-off-by: Álvaro Fernández Rojas --- src/config.c | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/config.c b/src/config.c index 7b0b8fa..fa5e3ef 100644 --- a/src/config.c +++ b/src/config.c @@ -1405,14 +1405,50 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr if ((c = tb[IFACE_ATTR_RA_ADVROUTER])) iface->ra_advrouter = blobmsg_get_bool(c); - if ((c = tb[IFACE_ATTR_RA_MININTERVAL])) - iface->ra_mininterval = blobmsg_get_u32(c); - - if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])) - iface->ra_maxinterval = blobmsg_get_u32(c); + /* + * RFC4861: MaxRtrAdvInterval: MUST be no less than 4 seconds and no greater than 1800 seconds. + * RFC8319: MaxRtrAdvInterval: MUST be no less than 4 seconds and no greater than 65535 seconds. + * Default: 600 seconds + */ + if ((c = tb[IFACE_ATTR_RA_MAXINTERVAL])){ + uint32_t ra_maxinterval = blobmsg_get_u32(c); + if (ra_maxinterval < 4) + ra_maxinterval = 4; + else if (ra_maxinterval > MaxRtrAdvInterval) + ra_maxinterval = MaxRtrAdvInterval; + iface->ra_maxinterval = ra_maxinterval; + } - if ((c = tb[IFACE_ATTR_RA_LIFETIME])) - iface->ra_lifetime = blobmsg_get_u32(c); + /* + * RFC4861: MinRtrAdvInterval: MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. + * Default: 0.33 * MaxRtrAdvInterval If MaxRtrAdvInterval >= 9 seconds; otherwise, the + * Default is MaxRtrAdvInterval. + */ + if ((c = tb[IFACE_ATTR_RA_MININTERVAL])){ + uint32_t ra_mininterval = blobmsg_get_u32(c); + if (ra_mininterval < MinRtrAdvInterval) + ra_mininterval = MinRtrAdvInterval; // clamp min + else if (ra_mininterval > (0.75 * (uint32_t)iface->ra_maxinterval)) + ra_mininterval = 0.75 * (uint32_t)iface->ra_maxinterval; // clamp max + iface->ra_mininterval = ra_mininterval; + } + + /* + * RFC4861: AdvDefaultLifetime: MUST be either zero or between MaxRtrAdvInterval and 9000 seconds. + * RFC8319: AdvDefaultLifetime: MUST be either zero or between MaxRtrAdvInterval and 65535 seconds. + * Default: 3 * MaxRtrAdvInterval + * i.e. 3 * 65535 => 65535 seconds. + */ + if ((c = tb[IFACE_ATTR_RA_LIFETIME])){ + uint32_t ra_lifetime = blobmsg_get_u32(c); + if (ra_lifetime != 0){ + if (ra_lifetime < (uint32_t)iface->ra_maxinterval) + ra_lifetime = (uint32_t)iface->ra_maxinterval; // clamp min + else if (ra_lifetime > AdvDefaultLifetime) + ra_lifetime = AdvDefaultLifetime; // clamp max + } + iface->ra_lifetime = ra_lifetime; + } if ((c = tb[IFACE_ATTR_RA_DNS])) iface->ra_dns = blobmsg_get_bool(c); -- 2.30.2